﻿using System;
using System.Collections;

namespace JsonParser
{
	public class TrimmableIndexString : ITrimmableIndexString, IEnumerable, IEnumerator
	{
		private string _baseValue;
		private int _startIndex;
		private int _endIndex;
		private int _currentIndex = 0;

		public TrimmableIndexString(string baseValue)
		{
			this._baseValue = baseValue;
			this._startIndex = 0;
			this._endIndex = this._baseValue.Length;
		}
		private TrimmableIndexString(string baseValue, int startIndex, int length)
		{
			this._baseValue = baseValue;
			this._startIndex = startIndex;
			this._endIndex = this._startIndex + length;
		}

		public char this[int index]
		{
			get
			{
				return this._baseValue[this._startIndex + index];
			}
		}

		public int CompareTo(TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}

		public bool Contains(TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}

		public bool EndsWith(TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}
		public bool EndsWith(TrimmableIndexString value, bool ignoreCase)
		{
			throw new NotImplementedException();
		}

		public bool Equals(TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}

		public int IndexOf(char value)
		{
			return IndexOf(value, 0, Length);
		}
		public int IndexOf(TrimmableIndexString value)
		{
			return IndexOf(value, 0, Length);
		}
		public int IndexOf(char value, int startIndex)
		{
			return IndexOf(value, startIndex, Length - startIndex);
		}
		public int IndexOf(TrimmableIndexString value, int startIndex)
		{
			return IndexOf(value, startIndex, Length - startIndex);
		}
		public int IndexOf(char value, int startIndex, int count)
		{
			if (startIndex < 0 || startIndex >= Length || startIndex + count > Length)
			{
				throw new ArgumentOutOfRangeException();
			}
			return this._baseValue.IndexOf(value, this._startIndex + startIndex, count) - this._startIndex;
		}
		public int IndexOf(TrimmableIndexString value, int startIndex, int count)
		{
			if (startIndex < 0 || startIndex >= Length || startIndex + count > Length)
			{
				throw new ArgumentOutOfRangeException();
			}
			return this._baseValue.IndexOf(value.ToString(), this._startIndex + startIndex, count) - this._startIndex;
		}

		public int IndexOfAny(char[] anyOf)
		{
			throw new NotImplementedException();
		}
		public int IndexOfAny(char[] anyOf, int startIndex)
		{
			throw new NotImplementedException();
		}
		public int IndexOfAny(char[] anyOf, int startIndex, int count)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString Insert(int startIndex, TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}

		public int LastIndexOf(char value)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOf(TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOf(char value, int startIndex)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOf(TrimmableIndexString value, int startIndex)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOf(char value, int startIndex, int count)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOf(TrimmableIndexString value, int startIndex, int count)
		{
			throw new NotImplementedException();
		}

		public int LastIndexOfAny(char[] anyOf)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOfAny(char[] anyOf, int startIndex)
		{
			throw new NotImplementedException();
		}
		public int LastIndexOfAny(char[] anyOf, int startIndex, int count)
		{
			throw new NotImplementedException();
		}

		public int Length
		{
			get
			{
				return this._endIndex - this._startIndex;
			}
		}

		public TrimmableIndexString PadLeft(int totalWidth)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString PadLeft(int totalWidth, char paddingChar)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString PadRight(int totalWidth)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString PadRight(int totalWidth, char paddingChar)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString Remove(int startIndex)
		{
			return Substring(0, startIndex);
		}
		public TrimmableIndexString Remove(int startIndex, int count)
		{
			return this.ToString().Remove(startIndex, count);
		}

		public TrimmableIndexString Replace(char oldValue, char newValue)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString Replace(TrimmableIndexString oldValue, TrimmableIndexString newValue)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString[] Split(char[] separator)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(TrimmableIndexString separator)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(TrimmableIndexString[] separator)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(char[] separator, int count)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(TrimmableIndexString separator, int count)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(TrimmableIndexString[] separator, int count)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(char[] separator, int count, StringSplitOptions options)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(TrimmableIndexString separator, int count, StringSplitOptions options)
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString[] Split(TrimmableIndexString[] separator, int count, StringSplitOptions options)
		{
			throw new NotImplementedException();
		}

		public bool StartsWith(TrimmableIndexString value)
		{
			throw new NotImplementedException();
		}
		public bool StartsWith(TrimmableIndexString value, bool ignoreCase)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString Substring(int index)
		{
			return Substring(index, Length - index);
		}
		public TrimmableIndexString Substring(int index, int length)
		{
			if (index < 0 || index > Length || length < 0 || index + length > Length)
			{
				throw new IndexOutOfRangeException();
			}
			return new TrimmableIndexString(this._baseValue, this._startIndex + index, length);
		}

		public char[] ToCharArray()
		{
			throw new NotImplementedException();
		}
		public char[] ToCharArray(int startIndex, int length)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString ToLower()
		{
			return new TrimmableIndexString(ToString().ToLower());
		}

		public override string ToString()
		{
			return this._baseValue.Substring(this._startIndex, Length);
		}

		public TrimmableIndexString ToUpper()
		{
			return new TrimmableIndexString(ToString().ToUpper());
		}

		public TrimmableIndexString Trim()
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString Trim(params char[] trimChars)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString TrimEnd()
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString TrimEnd(params char[] trimChars)
		{
			throw new NotImplementedException();
		}

		public TrimmableIndexString TrimStart()
		{
			throw new NotImplementedException();
		}
		public TrimmableIndexString TrimStart(params char[] trimChars)
		{
			throw new NotImplementedException();
		}

		public static implicit operator TrimmableIndexString(string value)
		{
			return new TrimmableIndexString(value);
		}

		#region IEnumerable<char>

		IEnumerator IEnumerable.GetEnumerator()
		{
			for (int i = 0; i < Length; i++)
			{
				yield return this[i];
			}
		}

		#endregion

		#region IEnumerator<char>

		public object Current
		{
			get
			{
				return this[this._currentIndex];
			}
		}

		public bool MoveNext()
		{
			if (this._currentIndex < Length)
			{
				this._currentIndex++;
				return true;
			}
			else
			{
				return false;
			}
		}

		public void Reset()
		{
			this._currentIndex = 0;
		}

		#endregion
	}
}
